use std::process::Command;
use winreg::transaction::Transaction;
use winreg::RegKey;
use winreg::enums::HKEY_CURRENT_USER;
use std::{env, fs};
use dialoguer::{Select, Confirm, Input};
use crate::prompt_theme::MyTheme;
use console::Term;
use url::Url;
use winapi::um::winuser::{SW_HIDE};
use crate::utils::{exec, get_proxy_url, MyData};
use std::path::Path;


pub struct  Config{}

impl Config{

    pub fn run(&self,lang:&str) {
        match lang {
            ""   => {
                let selections = &[
                    "PHP Composer",
                    "GO",
                    "Rust",
                    "Python",
                    "Node NPM",
                    "Flutter",
                    "Git",
                ];

                let selection = Select::with_theme(&MyTheme::custom())
                    .with_prompt("请选择语言:")
                    .items(&selections[..])
                    .interact_opt()
                    .unwrap();
                if let Some(selection) = selection {
                    // println!("selection is {}",selection);
                    // println!("选项：{}",selections[selection]);
                    match selection {
                        0 => self.php(),
                        1 => self.go(),
                        2 => self.rust(),
                        3 => self.python(),
                        4 => self.node(),
                        5 => self.flutter(),
                        6 => self.git(),
                        _ => println!("没有匹配到 {} 或暂时不支持",selections[selection])
                    }
                }else {
                    println!("你没有选择任何选项")
                }
            },
            "php" | "composer" => self.php(),
            "go" => self.go(),
            "rust" => self.rust(),
            "python" | "pip" => self.python(),
            "node" | "npm" => self.node(),
            "flutter"  => self.flutter(),
            "git"  => self.git(),
            _ => println!("没有匹配到 {} 或暂时不支持",lang)
        }
    }
    /// 配置PHP
   pub fn php(&self){
        let mut sources = MyData::new();
        sources.add("阿里云","https://mirrors.aliyun.com/composer/");
        sources.add("腾讯云","https://mirrors.cloud.tencent.com/composer/");
        sources.add("laravel-china","https://packagist.laravel-china.org");
        sources.add("华为云","https://mirrors.huaweicloud.com/repository/php/");
        sources.add("官方源","https://repo.packagist.org");


        let selection = Select::with_theme(&MyTheme::custom())
            .with_prompt("请选择php镜像源:")
            .default(0)
            .items(&sources.names)
            .interact()
            .unwrap();
        let config_command = format!("composer config -g repo.packagist composer {}",sources.values[selection]);
        // println!("如果没有执行成功，请在手动在cmd中执行： {}",config_command);
        println!("Run command:\r\n{}",config_command);

        let _status = Command::new("powershell.exe")
            .arg(config_command)
            .status()
            .unwrap();
        // println!("{}",status);
        // 查看状态
        let _status = Command::new("powershell.exe")
            .arg("composer config -g --absolute repositories.packagist.org")
            .status()
            .unwrap();
        // println!("{}",status);
    }

    /// 配置go
    pub fn go(&self){
        let mut sources = MyData::new();
        sources.add("goproxy.io","https://goproxy.io");
        sources.add("goproxy.cn","https://goproxy.cn");
        sources.add("阿里云","https://mirrors.aliyun.com/goproxy/");


        let selection = Select::with_theme(&MyTheme::custom())
            .with_prompt("请选择GOPROXY镜像源:")
            .default(0)
            .items(&sources.names)
            .interact()
            .unwrap();
        let env_proxy_key = "GOPROXY";
        let env_proxy_value = format!("{}", sources.values[selection]);
        println!("开始配置go");

        // 创建事务
        let t = Transaction::new().unwrap();
        let hkcu = RegKey::predef(HKEY_CURRENT_USER);
        let (key,_disp) = hkcu.create_subkey_transacted("Environment",&t).unwrap();

        println!("添加环境变量：{}：{}",env_proxy_key,env_proxy_value);
        key.set_value(env_proxy_key,&env_proxy_value).unwrap();

        // 提交事务
        t.commit().unwrap();
        println!("配置完成");
    }

    /// 配置rust
    pub fn rust(&self){

        let mut sources = MyData::new();
        sources.add("官方源","crates-io");
        sources.add("tuna","tuna");
        sources.add("sjtu","sjtu");
        sources.add("ustc","ustc");
        sources.add("rustcc","rustcc");
        sources.add("rustcc1","rustcc1");
        sources.add("rustcc2","rustcc2");


        let selection = Select::with_theme(&MyTheme::custom())
            .with_prompt("请选择Cargo镜像源:")
            .default(6)
            .items(&sources.names)
            .interact()
            .unwrap();

        // 是否启用代理
        let mut set_proxy = "".to_string();
        if Confirm::with_theme(&MyTheme::custom())
            .with_prompt("是否开启代理？")
            .default(false)
            .interact()
            .unwrap()
        {
            // 配置代理
            // let input:String = Input::new()
            //     .with_prompt("输入代理地址")
            //     .interact_text()
            //     .unwrap();
            let term = Term::buffered_stderr();

            let proxy_url = get_proxy_url().unwrap_or("127.0.0.1:7890".to_string());
            let input: String = Input::new()
                .default(proxy_url)
                .with_prompt("请输入代理地址：").
                interact_on(&term)
                .unwrap();
            println!("{}",input);

            set_proxy = format!(r#"
[http]
proxy = "{}"

[https]
proxy = "{}"
"#,input,input);
        }

        let replace_source;
        if selection == 0 {
            replace_source = "".to_string();
        }else {
            replace_source = format!("replace-with = '{}'",sources.values[selection]);
        }

        let config = format!(r#"
# replace with your favourite mirror

[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"

{}

[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"

[source.sjtu]
registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index"

[source.rustcc]
registry = "https://code.aliyun.com/rustcc/crates.io-index.git"

[source.rustcc1]
registry="git://crates.rustcc.cn/crates.io-index"

[source.rustcc2]
registry="git://crates.rustcc.com/crates.io-index"

# static 推荐在项目中配置
#[target.x86_64-pc-windows-msvc]
#rustflags = ["-C", "target-feature=+crt-static"]";

# use proxy
#[http]
#proxy = "127.0.0.1:7890"

#[https]
#proxy = "127.0.0.1:7890"
{}

# https://doc.rust-lang.org/cargo/reference/config.html?highlight=alias#configuration-format
[alias]     # command aliases
b = "build"
br = "build --release"
c = "check"
t = "test"
r = "run"
rr = "run --release"

"#,replace_source,set_proxy);

        println!("{}",config);
        println!("config_rust");

        // 获取当前 用户目录
        let cargo_path = env::var("USERPROFILE").unwrap() + "\\.cargo";
        if Path::new(cargo_path.as_str()).exists() {
            let config_path = cargo_path + "\\config";
            println!("将: \r\n {} \r\n写入到 {} 文件中",config,config_path);
            fs::write(config_path,config).unwrap();
            println!("rust 国内源配置完成");
        }else {
            println!("{} 不存在,rust可能还未安装",cargo_path);
        }
    }

    /// 配置 pip
    /// 以管理员身份运行 powershell 执行配置命令
    /// pip config --global set global.index-url https://mirrors.aliyun.com/pypi/simple/ | pip config --global set install.trusted-host mirrors.aliyun.com
    /// powershell 连续多条命令用 `|` ,cmd 连续多条命令用 `&&`
    pub fn python(&self) {
        let mut sources = MyData::new();
        sources.add("清华","https://pypi.tuna.tsinghua.edu.cn/simple");
        sources.add("阿里云","https://mirrors.aliyun.com/pypi/simple/");
        sources.add("中国科技大学","https://pypi.mirrors.ustc.edu.cn/simple/");
        sources.add("豆瓣","https://pypi.douban.com/simple/");
        sources.add("官方源","https://pypi.python.org/simple");


        let selection = Select::with_theme(&MyTheme::custom())
            .with_prompt("请选择pip镜像源:")
            .default(0)
            .items(&sources.names)
            .interact()
            .unwrap();

        // 解析url
        let issue_list_url = Url::parse(sources.values[selection]).unwrap();
        let source_host =issue_list_url.host_str().unwrap();

        let config_command = format!("pip config --global set global.index-url {} | pip config --global set install.trusted-host {}",sources.values[selection],source_host);
        // println!("如果没有执行成功，请在手动在cmd中执行： {}",config_command);
        println!("Run command:\r\n{}",config_command);


        exec("runas","powershell.exe",config_command.as_str(),SW_HIDE);


        // println!("{}",status);
        println!("配置完成")
    }

    /// 配置python 通过直接写入配置文件
    pub fn python_writefile(&self){
        let config = r#"
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn  # trusted-host
"#;
        println!("config_python");
        // 获取当前 用户目录
        let pip_path = env::var("USERPROFILE").unwrap() + "\\pip";
        let pip_path = pip_path.as_str();
        if !Path::new(&pip_path).exists() {
            fs::create_dir(pip_path).unwrap();
        }
        let config_path = pip_path.to_string() + "\\pip.ini";
        println!("将: \r\n {} \r\n写入到 {} 文件中",config,config_path);
        fs::write(config_path,config).unwrap();
        println!("pip 国内源配置完成");
    }

    /// 配置 node
    pub fn node(&self){
        let config_command = "npm config set registry https://registry.npm.taobao.org";

        println!("config_node");

        println!("执行命令: {}",config_command);

        let status = Command::new("powershell.exe")
            .arg(config_command)
            .status()
            .unwrap();
        println!("{}",status);
        let status = Command::new("powershell.exe")
            .arg(config_command)
            .status()
            .unwrap();
        println!("{}",status);
    }

    /// 配置flutter
    pub fn flutter(&self){
        let env_storage_key = "FLUTTER_STORAGE_BASE_URL";
        let env_storage_value = "https://storage.flutter-io.cn";

        let env_hosted_key = "PUB_HOSTED_URL";
        let env_hosted_value = "https://pub.flutter-io.cn";

        println!("config_flutter");

        // 创建事务
        let t = Transaction::new().unwrap();
        let hkcu = RegKey::predef(HKEY_CURRENT_USER);
        let (key,_disp) = hkcu.create_subkey_transacted("Environment",&t).unwrap();

        println!("添加环境变量：{}：{}",env_storage_key,env_hosted_value);
        key.set_value(env_storage_key,&env_storage_value).unwrap();

        println!("添加环境变量：{}：{}",env_hosted_key,env_hosted_value);
        key.set_value(env_hosted_key,&env_hosted_value).unwrap();
        // 提交事务
        t.commit().unwrap();
        println!("config flutter 完成");
    }

    /// 配置git 代理
    pub fn git(&self) {
        let selections = &[
            "添加代理",
            "取消代理",
        ];

        let selection = Select::with_theme(&MyTheme::custom())
            .with_prompt("Select: ")
            .items(&selections[..])
            .interact_opt()
            .unwrap();
        if let Some(selection) = selection {
            // println!("selection is {}",selection);
            // println!("选项：{}",selections[selection]);
            match selection {
                0 => self.add_git_proxy(),
                1 => self.remove_git_proxy(),
                _ => println!("没有匹配到 {} 或暂时不支持",selections[selection])
            }
        }else {
            println!("你没有选择任何选项")
        }
    }

    /// 添加代理
    fn add_git_proxy(&self) {
        let term = Term::buffered_stderr();
        let proxy_url = get_proxy_url().unwrap_or("127.0.0.1:7890".to_string());
        let input: String = Input::new()
            .default(proxy_url)
            .with_prompt("请输入代理地址：").
            interact_on(&term)
            .unwrap();
        // 占位符
        let command = format!("git config --global http.proxy http://{0} && git config --global https.proxy https://{0}",input);
        println!("command: {}",command);
        let _status = Command::new("cmd.exe")
            .arg("/C")
            .arg(command)
            .status()
            .unwrap();
    }

    /// 取消代理
    fn remove_git_proxy(&self) {
        let command ="git config --global --unset http.proxy && git config --global --unset https.proxy ";
        println!("command: {}",command);
        let _status = Command::new("cmd.exe")
            .arg("/C")
            .arg(command)
            .status()
            .unwrap();
    }

}
